package com.example.common.util;

import io.jsonwebtoken.Claims;
import io.jsonwebtoken.ExpiredJwtException;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

/**
 * @author benjamin_5
 * @Description token工具类
 * @date 2023/2/22
 */
public class JWTUtil {

    private final static Logger log = LoggerFactory.getLogger(JWTUtil.class);

    // jwt 加解密类型
    private static final SignatureAlgorithm ALGORITHM = SignatureAlgorithm.HS256;

    // jwt 生成密钥使用的密码 私钥
    private static final String SECRET = "asdkasdjad";

    // jwt 添加至http head中的前缀
    public static final String SEPARATOR = "Bearer ";

    // 添加到PAYLOAD的签发者
    private static final String ISSUE = "xxx";

    // 添加至PAYLOAD的有效期（秒）
    private static final int TIMEOUT = 60*60*24;

    // 参数名
    private static final String PARAM_NAME = "userId";

    /**
     * 生成token
     * @param userId
     * @return
     */
    public static String generateToken(String userId){
        // 创建PAYLOAD的私有声明（要放入token中的信息）
        Map<String,Object> claims = new HashMap<>();
        claims.put(PARAM_NAME,userId);
        long currentTime = System.currentTimeMillis();
        String token = Jwts.builder()
                // 唯一id
                .setId(UUID.randomUUID().toString())
                // 签发时间
                .setIssuedAt(new Date(currentTime))
                // 签发人
                .setIssuer(ISSUE)
                // 加密算法，私钥
                .signWith(ALGORITHM, SECRET)
                // 过期时间(毫秒)
                .setExpiration(new Date(currentTime + TIMEOUT * 1000))
                .addClaims(claims)
                .compact();
        return SEPARATOR + token;
    }

    public static String getUserId(String token){
        return (String) getVal(token, PARAM_NAME);
    }

    /**
     * 解析token 获取key
     * @param token
     * @param key
     * @return
     */
    public static Object getVal(String token,String key){
        return getClaimsBody(token).get(key);
    }

    /**
     * token是否过期
     * @param token
     * @return
     */
    public static boolean isExpiration(String token){
        try{
            return getClaimsBody(tokenHandler(token)).getExpiration().before(new Date());
        }catch (ExpiredJwtException e){
            return true;
        }
    }

    public static Claims getClaimsBody(String token){
        return Jwts.parser().setSigningKey(SECRET).parseClaimsJws(tokenHandler(token)).getBody();
    }

    private static String tokenHandler(String token){
        if(token.startsWith(SEPARATOR)){
            return token.split(" ")[1];
        }
        return token;
    }
}
